package iws.g5.uebung3;
import iws.g5.uebung3.enums.EventType;
import iws.g5.uebung3.gui.GuiConsole;
import iws.g5.uebung3.impls.Virus;
import iws.g5.uebung3.interfaces.LivingOrganicObject;
import iws.g5.uebung3.interfaces.OrganicObject;

import java.util.ArrayList;

/**
 * Timer for simulation control
 * @author t.ganzert
 *
 */
public class EventCalendar {
	
	final int SLEEP_TIME;
	final int ITERATIONS;

	private ArrayList<LivingOrganicObject> cells;
	private Simulator simulator;
	
	/**
	 * Constructor
	 * @param sleepTime time for an iteration
	 * @param iterations amount of iterations
	 */
	public EventCalendar(int sleepTime, int iterations, Simulator simulator){
		SLEEP_TIME=sleepTime;
		ITERATIONS=iterations;
		this.simulator=simulator;
		cells=new ArrayList<LivingOrganicObject>();
	}
	
	/**
	 * Start simulation and controll eventtriggering
	 */
	public void run(){	
		GuiConsole gui=new GuiConsole();
		for(int i=1;i<ITERATIONS;i++){
			try {
				triggerCellDivision(i);
				if(i%800 == 0) {
					triggerImmunization(i);
				}
				if(i%200 == 0) {
					triggerVirusAffection(i);
				}
				simulator.handleEndOfIteration();
				Thread.currentThread().sleep(SLEEP_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}
	
	/**
	 * Add LivingOrganicObject to element-list
	 * @param LivingOrganicObject
	 */
	public void subscribe(LivingOrganicObject livingObject){
		if(cells.contains(livingObject)==false){
			cells.add(livingObject);
		}
	}

	/**
	 * Remove LivingOrganicObject from the element list
	 * @param object
	 */
	public void unsubscribe(LivingOrganicObject object) {
		cells.remove(object);
	}
	
	/**
	 * Triggers CellDivision-Event for all LivingOrganicObject
	 */
	private void triggerCellDivision(int iteration){
		triggerEvent(iteration, EventType.CELLDIVISION);
	}
	
	/**
	 * Triggers Immunization-Event for all LivingOrganicObject
	 */
	private void triggerImmunization(int iteration){
		triggerEvent(iteration, EventType.IMMUNIZATION);
	}
	
	/**
	 * Triggers VirusAffection-Event for all LivingOrganicObject
	 */
	private void triggerVirusAffection(int iteration){
		triggerEvent(iteration, EventType.VIRUSAFFECTION);
	}
	
	/**
	 * Triggers an given event
	 */
	private void triggerEvent(int iteration, EventType event){
		ArrayList<LivingOrganicObject> cellsTemp = (ArrayList<LivingOrganicObject>)cells.clone();
		for(int i=0;i<cellsTemp.size();i++){
			cellsTemp.get(i).onEventTriggered(iteration, event);
		}
	}
	
	/**
	 * Event triggered before LivingOrganicObject do their work
	 * @param iteration
	 */
	public void triggerPreEvent(int iteration){
		
	}
	
	/**
	 * Event triggered after LivingOrganicObject do their work
	 * @param iteration
	 */
	public void triggerPostEvent(int itertion){
		
	}
	
}
